
PLUG.Platform = PLUG_PLATFORM_SHARED

PLUG.ClassName = "sh_unban"
PLUG.PrintName = "Player Unban Module"
PLUG.Author = "thomasfn"

if (SERVER) then

	local BanFile = "gmanage/bans.txt"

	function PLUG:Init()
		if (!file.Exists( BanFile )) then
			self:SaveBans()
		end
		local content = file.Read( BanFile )
		local b, res = pcall( glon.decode, content )
		if (!b) then
			ErrorNoHalt( "GMANAGE: Failed to load bans! (" .. (res or "No Error") .. ")\n" )
			return
		end
		self.BanList = res or {}
	end
	
	function PLUG:AddHooks()
		plugs.Hook( PLUG_PLATFORM_SERVER, "PlayerInitialSpawn" )
	end
	
	function PLUG:PlayerInitialSpawn( ply )
		ply:CheckBanStatus()
	end

	function PLUG:PlayerExtend( meta )
		function meta:BeamBans( to )
			to = to or self
			local banlist = plugs.Call( "GetBanList" ) or {}
			local tab = { "banlist", banlist }
			datastream.StreamToClients( to, "gmanage", tab )
		end
		function meta:CheckBanStatus()
			local banlist = plugs.Call( "GetBanList" )
			for _, v in pairs( banlist ) do
				if (v[1] == self:SteamID()) then
					if ((v[2] != 0) && (os.time() >= v[2])) then
						// Ban expired!
						plugs.Call( "TakeFromBanList", self:SteamID() )
						self:ChatPrint( "Your ban has expired. Don't take advantage." )
					else
						// Ban still in operation!
						local timeleft = math.ceil( (os.time() - v[2])/60 )
						self:Kick( "Banned for " .. timeleft .. " more minutes!" )
					end
				end
			end
		end
	end

	function PLUG:SaveBans()
		local b, res = pcall( glon.encode, self:GetBanList( true ) or {} )
		if (!b) then
			ErrorNoHalt( "GMANAGE: Failed to save bans! (" .. (res or "No Error") .. ")\n" )
			return
		end
		file.Write( BanFile, res )
		Msg( "Bans saved!\n" )
	end

	function PLUG:GetBanList( omitglobal )
		local c = self.BanList or {}
		// Compatability for global bans plug
		if (!omitglobal) then
			c = table.Copy( c )
			local res = plugs.Call( "GetGlobalBanList" )
			if (res) then table.Add( c, res ) end
		end
		return c
	end

	function PLUG:TakeFromBanList( steamid )
		plugs.Call( "RemoveGlobalBan", steamid )
		local bl = self:GetBanList( true )
		for k, v in pairs( bl ) do
			if (v[1] == steamid) then
				table.remove( bl, k )
				self:SaveBans()
				return
			end
		end
	end

	function PLUG:AddToBanList( steamid, duration, nick )
		local ctime = os.time()
		local bl = self:GetBanList( true )
		local endtime = ctime+duration
		if (duration == 0) then endtime = 0 end
		table.insert( bl, { steamid, endtime, nick } )
		self:SaveBans()
		plugs.Call( "AddGlobalBan", steamid, duration, nick )
	end

	function PLUG:DoConCommand( ply, com, args )
		if (com == "unban_beamtome") then
			if (!ply:HasPriv( "ban" )) then return end
			ply:BeamBans()
			return true
		end
		if (com == "unban_do") then
			if (!ply:HasPriv( "ban" )) then return end
			local steamid = args[1]
			if (!steamid) then return self:Err( ply, "Invalid steam id!" ) end
			self:TakeFromBanList( steamid )
			game.ConsoleCommand( "removeid " .. steamid .. "\n" )
			game.ConsoleCommand( "writeid\n" )
			ply:Log( "kickban", "Unbanned " .. steamid .. "" )
			plugs.CallHalt( "SendChatNotice", ply:Nick() .. " unbanned steamid " .. steamid .. "!", true )
			ply:PrintMessage( HUD_PRINTTALK, "Player unbanned!" )
			ply:BeamBans()
			return true
		end
	end

	function PLUG:Err( pl, msg )
		pl:PrintMessage( HUD_PRINTTALK, msg )
		return true
	end
	
end

if (CLIENT) then

	function PLUG:Init()
		plugs.Call( "AddMainMenuItem", "bansmenu", "Player Bans", "gmanage/ico_restrict", "ban" )
	end
	
	function PLUG:DataStream( tbl )
		if (tbl[1] == "banlist") then self.BanList = tbl[2] end
		if (plugs.Call( "GetCurrentSubMenuClass" ) == "bansmenu") then
			plugs.Call( "OpenSubMenu", "bansmenu" )
		end
	end
	
	function PLUG:BuildSubMenu( classname, window )
		if (classname == "bansmenu") then
			window:SetTitle( "Banned Players" )
			
			local tbl = vgui.Create( "DListView", window )
			tbl:SetPos( 5, 30 )
			tbl:SetSize( window:GetWide()-10, window:GetTall()-80 )
			tbl:AddColumn( "Name" )
			tbl:AddColumn( "Steam ID" )
			tbl:AddColumn( "Ban Ends" )
			local banlist = self.BanList or {}
			local cnt
			for cnt=1, #banlist do
				local tab = banlist[ cnt ]
				local endtime
				if (tab[2] == 0) then
					endtime = "Never"
				else
					local t = math.floor( (tab[2] - os.time())/60 )
					if (t < 0) then
						endtime = "EXPIRED"
					else
						endtime = tostring( t ) .. " mins"
					end
				end
				local l = tbl:AddLine( tab[3], tab[1], endtime )
				l.INFO = tab
			end
			
			local btn = vgui.Create( "DButton", window )
			btn:SetPos( 5, window:GetTall()-50 )
			btn:SetSize( window:GetWide()-10, 20 )
			btn:SetText( "Get Ban List" )
			function btn:DoClick()
				plugs.Call( "SendCommand", "unban_beamtome" )
			end
			
			local infopanel
			
			local function ShowInfo( INFO )
				if (infopanel) then infopanel:Remove() end
				local pn = vgui.Create( "DPanel", window )
				pn:SetPos( 5, window:GetTall()-25 )
				pn:SetSize( window:GetWide()-10, 20 )
				pn.Paint = function() end
				local lbl = vgui.Create( "DLabel", pn )
				lbl:SetText( INFO[3] .. " (" .. INFO[1] .. ")" )
				lbl:SizeToContents()
				lbl:SetPos( 0, 0 )
				local btn = vgui.Create( "DButton", pn )
				btn:SetText( "Unban" )
				btn:SetSize( pn:GetWide()*0.35, 20 )
				btn:SetPos( pn:GetWide() - btn:GetWide() - 5, 0 )
				function btn:DoClick()
					plugs.Call( "SendCommand", "unban_do", INFO[1] )
				end
				infopanel = pn
			end
			
			function tbl:OnRowSelected( row )
				local line = self:GetSelected()[ 1 ]
				ShowInfo( line.INFO )
			end
		end
	end

end